package frontend_package;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.AbstractTableModel;

import backend_package.Analyst;
import backend_package.Packet;

/**
 * Class for Analyst panel GUI and listeners
 * 
 * @author Aidana
 */
public class AnalystPanel extends Observable implements Observer {
	/** Analyst panel */
	private ImagePanel analystPanel;
	/** Button to open */
	private JButton openbutton;
	/** open new draft button */
	private JButton newdraftbutton;
	/** new notes button */
	private JButton newNotesButton;
	/** Draft RFP panel */
	private JPanel draftRFPpanel;
	/** assigned rfp panel */
	private JPanel assignedRFPpanel;
	/** south panel to hold buttons */
	private JPanel southPanel;
	/** draft and corresponding rfp table */
	private JTable draftRFPtable;
	/** assigned RFP's table */
	private JTable assignedRFPTable;
	/** scroll pane for draft rfp */
	private JScrollPane draftRFPscrollPane;
	/** scroll pane for assigned rfp */
	private JScrollPane assignedRFPscrollPane;
	/** assigned rfp column name */
	private String columnNamesAssignedRFP[];
	/** draft and rfp table column names */
	private String columnNamesRFPdraft[];
	/** assigned rfp gui */
	private String guiAssignedRFPs[][];
	/** rfp drafts return */
	private String guiRFPDrafts[][];
	/** background image */
	private Image myPicture = null;
	/** array of rfp paths */
	private String pathRFPdrafts[][];
	/** assigned rfp paths */
	private String pathAssignedRFPs[][];
	/** UserName */
	private String username;
	/** selected columns of draft and rfp table */
	private int[] selectedColumnsRFPdraft;
	/** selected row of rfp draft */
	private int selectedRowRFPdraft;
	/** selected rows of assigned rfp table */
	private int[] selectedRowsAssignedRFPs;
	/** which table index */
	private Integer whichTable;

	/**
	 * Constructor of Analyst panel
	 * 
	 * @author Aidana
	 * @author Eva
	 */
	public AnalystPanel() {
		// Create panel to hold all components
		username = "";
		whichTable = null;
		selectedRowsAssignedRFPs = null;
		selectedColumnsRFPdraft = null;
		URL url = getClass().getResource("/4.jpg");
		Image image = Toolkit.getDefaultToolkit().getImage(url);
		myPicture = image;

		analystPanel = new ImagePanel(myPicture, new BorderLayout());
		draftRFPpanel = new JPanel(new BorderLayout());

		southPanel = new JPanel(new GridLayout(1, 3));
		assignedRFPpanel = new JPanel(new BorderLayout());

		// Create default empty tables
		createColumnLabels();
		pathRFPdrafts = null;
		pathAssignedRFPs = null;
		guiAssignedRFPs = null;
		guiRFPDrafts = null;
		assignedRFPTable = new JTable(guiAssignedRFPs, columnNamesAssignedRFP);
		draftRFPtable = new JTable(guiRFPDrafts, columnNamesRFPdraft);
		draftRFPtable.setBackground(new Color(255, 255, 255));

		openbutton = new JButton("OPEN");
		openbutton.setRolloverEnabled(true);
		openbutton.setBackground(new Color(255, 255, 255));
		newdraftbutton = new JButton("NEW DRAFT");
		newdraftbutton.setRolloverEnabled(true);
		newdraftbutton.setBackground(new Color(255, 255, 255));

		newNotesButton = new JButton("NOTES");
		newNotesButton.setRolloverEnabled(true);
		newNotesButton.setBackground(new Color(255, 255, 255));
		newNotesButton.addActionListener(new NotesAnalystPanelListener());
		southPanel.add(openbutton);
		southPanel.add(newdraftbutton);
		southPanel.add(newNotesButton);

		// Add the table to a scrolling pane
		draftRFPscrollPane = new JScrollPane(draftRFPtable);
		draftRFPscrollPane.setBackground(new Color(255, 255, 255));
		draftRFPpanel.add(draftRFPscrollPane);
		assignedRFPscrollPane = new JScrollPane(assignedRFPTable);
		assignedRFPpanel.add(assignedRFPscrollPane);

		ImagePanel tablesWrapper = new ImagePanel(myPicture, new FlowLayout());
		tablesWrapper.setLayout(new FlowLayout());
		tablesWrapper.add(draftRFPpanel);
		tablesWrapper.add(assignedRFPpanel);

		analystPanel.add(tablesWrapper, BorderLayout.CENTER);
		analystPanel.add(southPanel, BorderLayout.SOUTH);

		setTableProperties();
		setLookNFeel();

	}

	/**
	 * Creates column names
	 * 
	 * @author Aidana
	 */

	private void createColumnLabels() {
		columnNamesRFPdraft = new String[2];
		columnNamesRFPdraft[0] = "Saved RFP's";
		columnNamesRFPdraft[1] = "Draft Responses";

		columnNamesAssignedRFP = new String[1];
		columnNamesAssignedRFP[0] = "Assigned RFP's";
	}

	/**
	 * Sets specific table properties
	 * 
	 * @author Aidana
	 */
	private void setTableProperties() {
		draftRFPtable.setCellSelectionEnabled(true);
		draftRFPtable.getTableHeader().setReorderingAllowed(false);
		assignedRFPTable.getTableHeader().setReorderingAllowed(false);
		// Change selection color
		draftRFPtable.setSelectionForeground(Color.black);
		draftRFPtable.setSelectionBackground(Color.yellow);
		assignedRFPTable.setSelectionForeground(Color.black);
		assignedRFPTable.setSelectionBackground(Color.yellow);
		// no lines
		draftRFPtable.setShowGrid(false);
		draftRFPtable.setIntercellSpacing(new Dimension(0, 0));
		assignedRFPTable.setShowGrid(false);
		assignedRFPTable.setIntercellSpacing(new Dimension(0, 0));
	}

	/**
	 * Makes the design of buttons look better
	 * 
	 * @author Syrym
	 */
	private void setLookNFeel() {

		NimbusLookAndFeel nimbus = new NimbusLookAndFeel();
		try {
			UIManager.setLookAndFeel(nimbus);
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Fills the tables
	 * 
	 * @author Syrym
	 */
	private void populateTables() {
		fillRFPDraftData();
		fillAssignedRFPData();
	}

	/**
	 * @author Aidana
	 * @author Eva - edited
	 * @author Syrym - edited
	 */
	private void fillRFPDraftData() {

		guiRFPDrafts = new String[pathRFPdrafts.length][2];
		for (int iY = 0; iY < pathRFPdrafts.length; iY++) {
			String rfp = pathRFPdrafts[iY][0];
			String draft = pathRFPdrafts[iY][1];

			int lastBSlash_0 = rfp.lastIndexOf('/');
			int lastBSlash_1 = draft.lastIndexOf('/');
			int length_0 = rfp.length();
			int length_1 = draft.length();

			guiRFPDrafts[iY][0] = rfp.substring(++lastBSlash_0, length_0);
			guiRFPDrafts[iY][1] = draft.substring(++lastBSlash_1, length_1);
		}
		draftRFPtable.setModel(new MyRFPDraftTableModel(guiRFPDrafts.length));
	}

	/**
	 * @author Aidana
	 * @author Eva - edited
	 * @author Syrym - edited
	 * @param theData
	 */
	private void fillAssignedRFPData() {
		guiAssignedRFPs = new String[pathAssignedRFPs.length][1];
		for (int iY = 0; iY < guiAssignedRFPs.length; iY++) {
			String rfp = pathAssignedRFPs[iY][0];
			int lastBSlash = rfp.lastIndexOf('/');
			int length = rfp.length();

			guiAssignedRFPs[iY][0] = rfp.substring(++lastBSlash, length);
		}
		assignedRFPTable.setModel(new MyAssignedRFPTableModel(
				guiAssignedRFPs.length));
	}

	/**
	 * @author Aidana
	 * @return analyst panel
	 */
	public JPanel getPanel() {
		return analystPanel;
	}

	/**
	 * New table model to make cells not editable
	 * 
	 * @author Aidana
	 */
	@SuppressWarnings("serial")
	public class MyRFPDraftTableModel extends AbstractTableModel {

		int rows;
		int columns;

		public MyRFPDraftTableModel(int r) {
			rows = r;
			columns = 2;
		}

		public boolean isEditable() {
			return false;
		}

		@Override
		public int getColumnCount() {
			// TODO Auto-generated method stub
			return columns;
		}

		@Override
		public int getRowCount() {
			// TODO Auto-generated method stub
			return rows;
		}

		@Override
		public String getColumnName(int c) {
			return columnNamesRFPdraft[c];
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			// TODO Auto-generated method stub
			return guiRFPDrafts[rowIndex][columnIndex];
		}
	}

	/**
	 * New Table model class to make table cells not editable
	 * 
	 * @author Aidana
	 * 
	 */
	@SuppressWarnings("serial")
	public class MyAssignedRFPTableModel extends AbstractTableModel {

		int rows;
		int columns;

		public MyAssignedRFPTableModel(int r) {
			rows = r;
			columns = 1;
		}

		public boolean isEditable() {
			return false;
		}

		@Override
		public int getColumnCount() {
			// TODO Auto-generated method stub
			return columns;
		}

		@Override
		public int getRowCount() {
			// TODO Auto-generated method stub
			return rows;
		}

		@Override
		public String getColumnName(int c) {
			return columnNamesAssignedRFP[c];
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			// TODO Auto-generated method stub
			return guiAssignedRFPs[rowIndex][columnIndex];
		}
	}

	/**
	 * Populates the table
	 * 
	 * @author Syrym
	 * @param packet
	 *            Packet
	 */
	private void setUserDataTable(Packet packet) {
		username = packet.getUsername();
		pathAssignedRFPs = (String[][]) packet.get(0);
		pathRFPdrafts = (String[][]) packet.get(1);
		populateTables();
	}

	/**
	 * Adds listeners to open and new draft buttons
	 * 
	 * @author Syrym
	 * @param listeners
	 */
	public void addListener(Listeners listeners) {
		newdraftbutton.addActionListener(listeners.new NewDraftListener());
		openbutton.addActionListener(listeners.new OpenFileListener());

		draftRFPtable.getColumnModel().addColumnModelListener(
				listeners.new DraftTableColumnListener());
		ListSelectionModel draftRFPSelectModel = draftRFPtable
				.getSelectionModel();
		draftRFPSelectModel
				.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		draftRFPSelectModel
				.addListSelectionListener(listeners.new DraftTableListListener());

		ListSelectionModel assignedRFPSelectModel = assignedRFPTable
				.getSelectionModel();
		assignedRFPSelectModel
				.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		assignedRFPSelectModel
				.addListSelectionListener(listeners.new AssignedTableListListener());
	}

	/**
	 * Implements Observer-observable design
	 * 
	 * @author Syrym
	 * @author Eva
	 */
	@Override
	public void update(Observable o, Object arg) {
		Packet packet = (Packet) arg;

		if (o instanceof Analyst && packet.getTag().equals("a_userdata_ap")) {
			setUserDataTable(packet);
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_selectedcols_draftrfp_ap")) {
			selectedColumnsRFPdraft = draftRFPtable.getSelectedColumns();
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_selectedrows_draftrfp_ap")) {
			whichTable = 0;
			selectedRowRFPdraft = draftRFPtable.getSelectedRow();
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_selectedrows_assigned_ap")) {
			whichTable = 1;
			selectedRowsAssignedRFPs = assignedRFPTable.getSelectedRows();
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_newdraft_ap")) {
			Object[] oarr = { pathRFPdrafts, pathAssignedRFPs, whichTable,
					selectedRowsAssignedRFPs };
			setChanged();
			notifyObservers(new Packet("ap_newdraft_lis", oarr, username));
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_updateddata_ap")) {
			setUserDataTable(packet);
		} else if (o instanceof Listeners
				&& packet.getTag().equals("lis_openfile_ap")) {
			Object[] oarr = { pathRFPdrafts, pathAssignedRFPs, whichTable,
					selectedRowsAssignedRFPs, selectedColumnsRFPdraft,
					selectedRowRFPdraft };
			setChanged();
			notifyObservers(new Packet("ap_openfile_lis", oarr, username));
		}

	}

	/**
	 * Notifies observers from notes analyst panel
	 * 
	 * @author Eva
	 * @author Zheng
	 * 
	 */
	class NotesAnalystPanelListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			setChanged();
			notifyObservers(new Packet("ap_openqpanel_m"));
		}
	}

	/**
	 * Class that draws background image to panel
	 * 
	 * @author Aidana
	 * 
	 */
	@SuppressWarnings("serial")
	class ImagePanel extends JPanel {

		private Image img;

		public ImagePanel(Image img, LayoutManager layout) {
			this.img = img;
			Dimension size = new Dimension(img.getWidth(null),
					img.getHeight(null));
			setPreferredSize(size);
			setMinimumSize(size);
			setMaximumSize(size);
			setSize(size);
			setLayout(null);
			super.setLayout(layout);
		}

		public void paintComponent(Graphics g) {
			g.drawImage(img, 0, 0, null);
		}

	}
}